package java8.predicate;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateTest {

    //使用简单的Predicate来过滤list中的name
    @Test
    public void test1() {
        //单条件
        List<String> names = Arrays.asList("Adam", "Alexander", "John", "Tom");
        List<String> result = names.stream()
                .filter(name -> name.startsWith("A"))
                .collect(Collectors.toList());
        result.forEach(System.out::println);

        //多条件
        result = names.stream()
                .filter(name -> name.startsWith("A"))
                .filter(name -> name.length() < 5)
                .collect(Collectors.toList());
        result.forEach(System.out::println);

        //复杂条件
        result = names.stream()
                .filter(name -> name.startsWith("A") && name.length() < 5)
                .collect(Collectors.toList());
        result.forEach(System.out::println);


    }

    // 组合使用Predicate
    @Test
    public void test2() {
        List<String> names = Arrays.asList("Adam", "Alexander", "John", "Tom");
        Predicate<String> predicate1 = str -> str.startsWith("A");
        Predicate<String> predicate2 =  str -> str.length() < 5;

        //Predicate.and() 两个条件都要满足
        List<String> result = names.stream()
                .filter(predicate1.and(predicate2))
                .collect(Collectors.toList());
        result.forEach(System.out::println);

        //Predicate.or() 满足其中一个即可
        result = names.stream()
                .filter(predicate1.or(predicate2))
                .collect(Collectors.toList());
        result.forEach(System.out::println);


        //Predicate.negate() 将此条件取反
        result = names.stream()
                .filter(predicate1.or(predicate2.negate()))
                .collect(Collectors.toList());
        result.forEach(System.out::println);



    }

    // 组合Predicates集合
    @Test
    public void test3() {
        List<String> names = Arrays.asList("Adam", "Alexander", "John", "Tom");
        List<Predicate<String>> allPredicates = new ArrayList<>();
        allPredicates.add(str -> str.startsWith("A"));
        allPredicates.add(str -> str.contains("d"));
        allPredicates.add(str -> str.length() > 4);

        List<String> result = names.stream()
                .filter(allPredicates.stream().reduce(x->true, Predicate::and))
                .collect(Collectors.toList());

        result.forEach(System.out::println);
    }

}
